package gradle.common.core.config;

import cn.hutool.core.date.DatePattern;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.TimeZone;

/**
 * <a href="https://spring.io/blog/2013/05/11/content-negotiation-using-spring-mvc">https://spring.io/blog/2013/05/11/content-negotiation-using-spring-mvc..</a>
 *
 * @author 1141193930@qq.com
 * Created by licl on 2025/11/20
 */
@Configuration
public class WebMvcConfigurerConfiguration implements WebMvcConfigurer {

    /**
     * 统一配置 Jackson 的日期格式与时区
     */
    @Bean
    public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN);

        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter));
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter));
        // 配置Java 8时间类型
        builder.serializers(new LocalDateTimeSerializer(formatter));
        builder.deserializers(new LocalDateTimeDeserializer(formatter));

        return builder.modules(javaTimeModule).timeZone(TimeZone.getTimeZone("Asia/Shanghai")).simpleDateFormat(DatePattern.NORM_DATETIME_PATTERN).serializationInclusion(JsonInclude.Include.ALWAYS).build();
    }

    /**
     * 注册转换器（不覆盖 Spring Boot 默认顺序，仅添加必要项）
     */
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 默认的 ByteArray/String/Resource 会自动配置，无需手动加入
        // 我们只需要确保 JSON converter 使用我们自定义的 ObjectMapper
        for (HttpMessageConverter<?> converter : converters) {
            if (converter instanceof MappingJackson2HttpMessageConverter jsonConverter) {
                jsonConverter.setObjectMapper(objectMapper(new Jackson2ObjectMapperBuilder()));
            }
        }
    }

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        // 靠 Accept header，不推荐 parameter
        configurer.defaultContentType(MediaType.APPLICATION_JSON);
    }
}
